﻿using System;
using System.Collections.Generic;

namespace Huazhu.PMS.Framework.Organization
{
    public class OrgTree
    {
        private readonly IDictionary<string, OrgTreeNode> _nodes = new Dictionary<string, OrgTreeNode>();

        public const string ROOT_NODE_ID = "0";

        /// <summary>
        /// 树上所有子节点，节点id为键
        /// </summary>
        internal IDictionary<string, OrgTreeNode> NodesOnTree
        {
            get { return _nodes; }
        }

        private IDictionary<string, ICollection<OrgTreeNode>> _areaIdIndex =
            new Dictionary<string, ICollection<OrgTreeNode>>();

        public IDictionary<string, ICollection<OrgTreeNode>> AreaIdIndex
        {
            get
            {
                return _areaIdIndex;
            }
        }

        internal OrgTree()
        {
        }

        private OrgTreeNode rootNode = new OrgTreeNode{ Id = ROOT_NODE_ID };

        public OrgTreeNode RootNode
        {
            get { return rootNode; }
        }

        public static OrgTreeNode CreateNode()
        {
            OrgTreeNode node = new OrgTreeNode();
            return node;
        }

        public static OrgTreeNode CreateNode(string nodeName)
        {
            OrgTreeNode node = CreateNode();
            node.NodeName = nodeName;
            return node;
        }

        public static OrgTreeNode CreateNode(string id, string nodeName)
        {
            OrgTreeNode node = CreateNode(nodeName);
            node.Id = id;
            return node;
        }

        /// <summary>
        /// 根据所给路径，返回指向的节点对象
        /// </summary>
        /// <param name="path">路径，eg:"root:/总部/华东区/上海东区/联洋店"</param>
        /// <returns></returns>
        public OrgTreeNode SelectNode(string path)
        {
            if (path == null || !path.Contains("/") || !path.StartsWith("root:"))
            {
                throw new ArgumentException("error path:" + path);

                //return null;
            }

            string[] nodesPaths = path.Split(new[]{"/"}, StringSplitOptions.RemoveEmptyEntries);

            if (!nodesPaths[0].Equals("root:"))
            {
                

                try
                {
                    throw new ArgumentException("error path:" + path);
                }
                catch (ArgumentException ae)
                {
                    //Htinns.Common.Logging.Logging.WriteExceptionLogToDataBase(ae, Htinns.Common.Logging.Logging.Priority_One, null, null, "operation denied");
                    return null;
                }
            }

            OrgTreeNode node = this.rootNode;

            for (int i = 1; i < nodesPaths.Length; i++)
            {
                Dictionary<string, OrgTreeNode> childs = node.ChildNodes as Dictionary<string, OrgTreeNode>;

                if (childs == null)
                {
                    continue;
                }

                if (!childs.ContainsKey(nodesPaths[i]))
                {
                    return null;
                }

                node = childs[nodesPaths[i]];
            }

            return node;
        }

        public OrgTreeNode FindNodeByName(string nodeFullName)
        {
            OrgTree tree = OrgTreeProvider.GetOrganizationTree();

            return tree.SelectNode(nodeFullName);
        }

        /// <summary>
        /// 根据所给部门id，返回指向的节点对象
        /// </summary>
        /// <param name="nodeId">部门id</param>
        /// <returns></returns>
        public OrgTreeNode SelectNodeById(string nodeId)
        {
            if (nodeId == null)
                return null;

            return (NodesOnTree.ContainsKey(nodeId) ? NodesOnTree[nodeId] : null);
        }

        public static OrgTreeNode FindNodeById(string nodeId)
        {
            OrgTree tree = OrgTreeProvider.GetOrganizationTree();

            return tree.SelectNodeById(nodeId);
        }

        /// <summary>
        /// 根据所给的部门完整路径名，给出部门id
        /// </summary>
        /// <param name="fullName"></param>
        /// <returns></returns>
        public string GetIdByNodeFullName(string fullName)
        {
            OrgTreeNode node = SelectNode(fullName);

            return (node == null) ? null : node.Id;
        }
    }
}
